/**
 * CommonUtil
 */
//命名空间
var BH = {};
BH.Interface = function (name,methods) {
    //判断接口参数的个数
    if(arguments.length!=2){
        throw new Error('this instance constructor arguments must be 2 length!');

    }
    this.name = name;
    this.methods = [];
    for (var i = 0,len = methods.length;i<len;i++){
        if(typeof methods[i]!=='string'){
            throw new Error('the interface method name is error!');
        }
        this.methods.push(methods[i]);
    }
}
//检验接口里的方法
BH.Interface.ensureImplements = function (object) {
    if(arguments.length<2){
        throw new Error('Interface.ensureImplements method constructor arguments must be>=2!');
    }
    //获得接口实例对象
    for(var i = 1,len=arguments.length;i<len;i++){
        var instanceInterface = arguments[i];
        //判断参数是否是接口类型
        if(instanceInterface.constructor!==BH.Interface){
            throw new Error('the arguments constructor not be Interface class ');
        }
        //循环接口实例对象中的每一个方法
        for(var j = 0;j<instanceInterface.methods.length;j++){
            var methodName = instanceInterface.methods[j];
            if(!object[methodName] || typeof object[methodName]!=='function'){
                throw new Error("the method name "+methodName+" is not found");
            }
        }
    }
}
BH.extend = function (sub,sup) {
    //目的：只继承父类的原型对象
    //创建一个空函数，目的，空函数进行中转
    var F = new Function();
    //实现空函数原型对象和超类原型对象的转换
    F.prototype = sup.prototype;
    //原型继承
    sub.prototype = new F();
    //还原子类的构造器
    sub.prototype.constructor = sub;
    //保存一下父类的原型对象，一方面方便解耦，另一方面方便获得父类的原型对象
    sub.superClass = sup.prototype;  //自定义一个子类的静态属性，接收父类的原型对象
    //判断父类的原型对象的构造器
    if(sup.prototype.constructor==Object.prototype.constructor){
        //手动还原父类原型对象的构造器
        sup.prototype.constructor = sup;

    }
}
//定义对象EventUtil
BH.EventUtil = {
    /**
     * 添加事件监听
     * @param element html元素
     * @param type 事件类型 例如 click,load
     * @param handler 监听函数
     */
    addHandler : function(element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    },
    /**
     * 移除事件监听
     * @param element html元素
     * @param type 事件类型 例如 click,load
     * @param handler 要移除的监听函数
     */
    removeHandler : function(element, type, handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent("on" + type, handler);
        } else {
            element["on" + type] = null;
        }
    },
    /**
     * 获取Event事件对象
     */
    getEvent : function(event) {
        return event || window.event;
    },
    /**
     * 获取事件源 例如 用鼠标点击页面上某个元素，即是获取被点击的元素
     */
    getTarget : function(event) {
        return event.target || event.srcElement;
    }
}

/**
 * 获取style 风格
 * @param el html元素
 * @param style 具体的风格名称 比如width height
 */
BH.getStyle = function(el, style) {
    if (el.currentStyle) {
        style = style.replace(/\-(\w)/g, function(all, letter) {
            return letter.toUpperCase();
        });
        var value = el.currentStyle[style];
        return value;
    } else {
        return document.defaultView.getComputedStyle(el, null)
            .getPropertyValue(style);
    }
}
/**
 * 显示或隐藏元素  如果元素是显示的则隐藏，如果是隐藏则显示
 * @param element html元素
 */
BH.toggleDisplay = function(element) {
    var display = getStyle(element, "display");
    if (display == "none") {
        element.style.display = "block";
    } else {
        element.style.display = "none";
    }
}
Array.prototype.each = function (fn) {
    try {
        /**
         * 遍历数组每一项，记录当前遍历的元素位置
         */
        this.i || (this.i=0);
        if(this.length>0 && fn.constructor==Function){
            //循环遍历数组的每一项
            while (this.i<this.length){
                var e =  this[this.i];
                //如果当前元素获取到了，并且当前元素是一个数组
                if(e && e.constructor==Array){
                    e.each(fn);
                }else{
                    //把数组的当前元素传递给fn函数，并让函数执行。
                    //fn.apply(e,[e]);
                    fn.call(e,e);
                }
                this.i++;
            }
            //释放内存，垃圾回收机制回收变量
            this.i = null;
        }
    } catch (ex){
    }
    return this;
}